const { chromium } = require('playwright');
const { chromium: chromiumExtra } = require('playwright-extra');
const stealth = require('puppeteer-extra-plugin-stealth')();
const EcommerceCrawler = require('./ecommerce-crawler');

/**
 * 任务管理器 - 管理多个爬虫任务的执行
 */
class TaskManager {
    constructor(options = {}) {
        this.browser = null;
        this.tasks = [];
        this.results = [];
        this.options = {
            headless: options.headless || false,
            slowMo: options.slowMo || 1000,
            maxConcurrent: options.maxConcurrent || 3, // 最大并发数
            stealth: options.stealth !== undefined ? options.stealth : false, // 是否使用 stealth 模式
            ...options
        };
    }

    /**
     * 添加爬取任务
     * @param {Object} siteConfig - 网站配置对象
     */
    addTask(siteConfig) {
        if (!siteConfig || !siteConfig.url) {
            throw new Error('网站配置必须包含url属性');
        }
        
        this.tasks.push(siteConfig);
        console.log(`✅ 添加任务: ${siteConfig.name || siteConfig.url}`);
        return this;
    }

    /**
     * 批量添加任务
     * @param {Array} siteConfigs - 网站配置数组
     */
    addTasks(siteConfigs) {
        siteConfigs.forEach(config => this.addTask(config));
        return this;
    }

    /**
     * 初始化浏览器
     */
    async init() {
        if (!this.browser) {
            const stealthMode = this.options.stealth ? '(Stealth 模式)' : '';
            console.log(`🚀 正在启动浏览器... ${stealthMode}`);
            
            const launchOptions = {
                headless: this.options.headless,
                slowMo: this.options.slowMo
            };
            
            if (this.options.stealth) {
                // 使用 playwright-extra 和 stealth 插件
                chromiumExtra.use(stealth);
                this.browser = await chromiumExtra.launch(launchOptions);
                console.log('✅ 浏览器启动成功！(已启用 Stealth 隐身模式)');
            } else {
                // 使用普通 playwright
                this.browser = await chromium.launch(launchOptions);
                console.log('✅ 浏览器启动成功！');
            }
        }
    }

    /**
     * 执行单个任务
     * @param {Object} siteConfig - 网站配置
     * @param {Number} index - 任务索引
     */
    async executeTask(siteConfig, index) {
        const taskName = siteConfig.name || `任务${index + 1}`;
        console.log(`\n📋 [${index + 1}/${this.tasks.length}] 开始执行: ${taskName}`);
        
        try {
            // 创建新页面
            const page = await this.browser.newPage();
            
            // 设置用户代理
            await page.setExtraHTTPHeaders({
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
            });

            // 创建爬虫实例（不需要初始化浏览器）
            const crawler = new EcommerceCrawler();
            crawler.browser = this.browser;
            crawler.page = page;

            // 执行爬取
            let result;
            if (typeof siteConfig.customCrawl === 'function') {
                // 使用自定义爬取逻辑
                result = await siteConfig.customCrawl(page, crawler);
            } else {
                // 使用默认爬取逻辑
                await page.goto(siteConfig.url, {
                    waitUntil: 'networkidle',
                    timeout: siteConfig.crawlOptions?.timeout || 30000
                });
                
                const title = await page.title();
                result = {
                    success: true,
                    url: siteConfig.url,
                    title: title,
                    timestamp: new Date().toISOString()
                };
            }

            // 关闭页面
            await page.close();

            console.log(`✅ [${index + 1}/${this.tasks.length}] ${taskName} 执行成功`);
            return {
                taskName,
                config: siteConfig,
                ...result
            };

        } catch (error) {
            console.error(`❌ [${index + 1}/${this.tasks.length}] ${taskName} 执行失败:`, error.message);
            return {
                taskName,
                config: siteConfig,
                success: false,
                error: error.message,
                timestamp: new Date().toISOString()
            };
        }
    }

    /**
     * 并发执行所有任务
     */
    async runParallel() {
        console.log(`\n🔄 并发模式: 同时执行 ${this.tasks.length} 个任务\n`);
        
        await this.init();

        const startTime = Date.now();
        
        // 使用 Promise.all 并发执行所有任务
        this.results = await Promise.all(
            this.tasks.map((task, index) => this.executeTask(task, index))
        );

        const duration = ((Date.now() - startTime) / 1000).toFixed(2);
        this.printSummary('并发', duration);
        
        return this.results;
    }

    /**
     * 顺序执行所有任务
     */
    async runSequential() {
        console.log(`\n⏭️  顺序模式: 按顺序执行 ${this.tasks.length} 个任务\n`);
        
        await this.init();

        const startTime = Date.now();
        this.results = [];

        // 逐个执行任务
        for (let i = 0; i < this.tasks.length; i++) {
            const result = await this.executeTask(this.tasks[i], i);
            this.results.push(result);
            
            // 任务间延迟（除了最后一个任务）
            if (i < this.tasks.length - 1) {
                const delay = this.options.delayBetweenTasks || 1000;
                console.log(`⏱️  等待 ${delay}ms 后执行下一个任务...`);
                await new Promise(resolve => setTimeout(resolve, delay));
            }
        }

        const duration = ((Date.now() - startTime) / 1000).toFixed(2);
        this.printSummary('顺序', duration);
        
        return this.results;
    }

    /**
     * 限制并发数的并发执行
     */
    async runConcurrent(maxConcurrent = null) {
        const limit = maxConcurrent || this.options.maxConcurrent;
        console.log(`\n🔀 限制并发模式: 最多同时执行 ${limit} 个任务（共 ${this.tasks.length} 个）\n`);
        
        await this.init();

        const startTime = Date.now();
        this.results = [];

        // 将任务分批执行
        for (let i = 0; i < this.tasks.length; i += limit) {
            const batch = this.tasks.slice(i, i + limit);
            const batchResults = await Promise.all(
                batch.map((task, batchIndex) => this.executeTask(task, i + batchIndex))
            );
            this.results.push(...batchResults);

            // 批次间延迟（除了最后一批）
            if (i + limit < this.tasks.length) {
                const delay = this.options.delayBetweenBatches || 2000;
                console.log(`\n⏱️  批次完成，等待 ${delay}ms 后执行下一批...\n`);
                await new Promise(resolve => setTimeout(resolve, delay));
            }
        }

        const duration = ((Date.now() - startTime) / 1000).toFixed(2);
        this.printSummary(`限制并发(${limit})`, duration);
        
        return this.results;
    }

    /**
     * 打印执行摘要
     */
    printSummary(mode, duration) {
        const successCount = this.results.filter(r => r.success).length;
        const failCount = this.results.length - successCount;

        console.log('\n' + '='.repeat(60));
        console.log(`📊 执行摘要 (${mode}模式)`);
        console.log('='.repeat(60));
        console.log(`总任务数: ${this.results.length}`);
        console.log(`成功: ${successCount} ✅`);
        console.log(`失败: ${failCount} ❌`);
        console.log(`总耗时: ${duration}秒`);
        console.log('='.repeat(60) + '\n');
    }

    /**
     * 获取结果
     */
    getResults() {
        return this.results;
    }

    /**
     * 获取成功的结果
     */
    getSuccessResults() {
        return this.results.filter(r => r.success);
    }

    /**
     * 获取失败的结果
     */
    getFailedResults() {
        return this.results.filter(r => !r.success);
    }

    /**
     * 关闭浏览器
     */
    async close() {
        if (this.browser) {
            await this.browser.close();
            console.log('🔚 浏览器已关闭');
        }
    }

    /**
     * 清空任务列表
     */
    clearTasks() {
        this.tasks = [];
        this.results = [];
        console.log('🗑️  任务列表已清空');
        return this;
    }
}

module.exports = TaskManager;

